<template>
  <Drawer
    :visible="visible"
    :title="type === 1 ? '新增用户' : '编辑用户'"
    size="large"
    @ok="handleOk"
    @close="handleCancel"
    :destroy-on-close="true"
  >
    <template #footer>
      <div class="float-right">
        <Button key="back" class="mr-10px" @click="handleCancel">返回</Button>
        <Button key="submit" type="primary" @click="handleOk">确认</Button>
      </div>
    </template>
    <div class="centent">
      <Form
        ref="formRef"
        :model="formState"
        :rules="rules"
        :labelCol="{ style: { width: '80px' } }"
        :wrapper-col="{ style: { width: '180px' } }"
        :colon="false"
      >
        <Row>
          <Col :span="24">
            <FormItem label="用户名" name="userName">
              <Input v-model:value="formState.userName" placeholder="请输入用户名" :disabled="type === 2" />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col :span="24">
            <FormItem label="姓名" name="name">
              <Input v-model:value="formState.name" placeholder="请输入姓名" />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col :span="12">
            <FormItem label="手机号码" name="phone" :rules="phoneRule">
              <Input
                v-model:value="formState.phone"
                placeholder="请输入手机号码"
                :disabled="!formState.isUpdatePhone && type === 2"
              />
            </FormItem>
          </Col>
          <Col :span="12" v-if="type === 2">
            <FormItem label="是否更新" name="isUpdatePhone" valuePropName="formState.isUpdatePhone">
              <Switch
                v-model:value="formState.isUpdatePhone"
                checked-children="Yes"
                un-checked-children="No"
                :checkedValue="true"
                :unCheckedValue="false"
                v-model:checked="formState.isUpdatePhone"
                @change="changePhoneStatus"
              />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col :span="12">
            <FormItem label="邮箱" name="email" :rules="emailRule">
              <Input
                v-model:value="formState.email"
                placeholder="请输入邮箱"
                :disabled="!formState.isUpdateEmail && type === 2"
              />
            </FormItem>
          </Col>
          <Col :span="12" v-if="type === 2">
            <FormItem label="是否更新" name="isUpdateEmail" valuePropName="formState.isUpdateEmail">
              <Switch
                v-model:value="formState.isUpdateEmail"
                checked-children="Yes"
                un-checked-children="No"
                :checkedValue="true"
                :unCheckedValue="false"
                v-model:checked="formState.isUpdateEmail"
                @change="changeEmailStatus"
              />
            </FormItem>
          </Col>
        </Row>
        <Row v-if="type === 1">
          <Col :span="12">
            <FormItem label="密码" name="password">
              <Input
                v-model:value="formState.password"
                placeholder="请输入密码"
                type="password"
                v-if="isNewIput"
                @change="pwdChange"
              >
                <template #suffix>
                  <a @click="encrypt"><EyeInvisibleOutlined style="color: rgba(0, 0, 0, 0.45)" /></a>
                </template>
              </Input>
              <Input v-model:value="formState.password" placeholder="请输入密码" v-if="!isNewIput" @change="pwdChange">
                <template #suffix>
                  <a @click="decrypt"><EyeOutlined style="color: rgba(0, 0, 0, 0.45)" /></a> </template
              ></Input>
            </FormItem>
          </Col>
          <Col :span="12">
            <FormItem label="确认密码" name="checkPassword">
              <InputPassword v-model:value="formState.checkPassword" placeholder="请输入密码"> </InputPassword>
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col :span="24">
            <FormItem label="所属组织" name="orgId">
              <TreeSelect
                v-model:value="formState.orgId"
                style="width: 100%"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                :fieldNames="replaceFields"
                :tree-data="treeData"
                :disabled="type === 2"
                @select="selectOrg"
                placeholder="请选择组织"
              >
              </TreeSelect>
            </FormItem>
          </Col>
        </Row>
        <Row>
          <FormItem label="状态" name="status" valuePropName="formState.status">
            <Switch
              v-model:value="formState.status"
              checked-children="启用"
              un-checked-children="停用"
              :checkedValue="1"
              :unCheckedValue="0"
              v-model:checked="formState.status"
              @change="changeStatus"
            />
          </FormItem>
        </Row>
        <Form ref="formRef2" :model="dynamicValidateForm">
          <Space v-for="(subApp, index) in dynamicValidateForm" :key="index" style="display: flex; margin-bottom: 8px">
            <Row>
              <Col :span="18">
                <FormItem
                  label="应用授权"
                  :name="[index, 'subAppId']"
                  :rules="{
                    required: true,
                    message: '请选择应用',
                  }"
                >
                  <Select
                    @select="handleSelect"
                    v-model:value="subApp.subAppId"
                    :options="
                      appIdList.map((a) => ({
                        value: a.id,
                        label: a.name,
                        key: index,
                        disabled: a.disabled,
                      }))
                    "
                    style="width: 170px"
                  ></Select>
                </FormItem>
              </Col>
              <Col :span="3">
                <FormItem
                  label="用户角色"
                  :name="[index, 'roleIds']"
                  :rules="{
                    required: true,
                    message: '请选择用户角色',
                  }"
                  style="width: 150px"
                >
                  <Select
                    mode="multiple"
                    v-model:value="subApp.roleIds"
                    :options="
                      (subApp.roleList || []).map((a) => ({
                        value: a.id,
                        label: a.name,
                      }))
                    "
                    style="width: 170px"
                  ></Select>
                </FormItem>
                <Col :span="3">
                  <MinusCircleOutlined
                    v-if="dynamicValidateForm.length > 1"
                    class="dynamic-delete-button ml-3px delete"
                    :disabled="dynamicValidateForm.length === 1"
                    @click="remove(index)"
                  />
                </Col>
              </Col>
            </Row>
          </Space>
        </Form>
        <Button style="" key="dashed" block @click="addSight">新增应用授权</Button>
      </Form>
    </div>
  </Drawer>
</template>
<script setup lang="ts">
import { ref, defineProps, reactive, watch, unref, nextTick } from 'vue';
import {
  Form,
  Drawer,
  FormItem,
  Input,
  message,
  TreeSelect,
  Button,
  Switch,
  InputPassword,
  Space,
  Row,
  Col,
  Select,
} from 'ant-design-vue';
import { MinusCircleOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue';
import { getSaaSOrgTree } from '/@/api/organization-mgmt/organization';
import { addSaaSUser, updateSaaSUser, findSaaSUserRoleById } from '/@/api/organization-mgmt/user';
import { SaaSOrgItem } from '/@/api/organization-mgmt/model/organizationModel';
import { SaaSRoleItem } from '/@/api/organization-mgmt/model/userModel';
import { getRoleBySubAppId, getSubAppList } from '/@/api/organization-mgmt/user';
import { viewSaaSUser } from '/@/api/organization-mgmt/user';
import { Rule } from 'ant-design-vue/lib/form';
import { ApiResultEnum } from '/@/enums/resEnum';

const formRef = ref();
const formRef2 = ref();

let props = defineProps({
  visible: Boolean,
  type: Number,
  user: Object,
});
interface AppRole {
  subAppId: string;
  idaasAppId: string;
  roleIds: string[];
  roleList: [];
}
interface User {
  userId: string;
  userName: string;
  name: string;
  password: string;
  checkPassword: string;
  email: string;
  isUpdatePhone: boolean;
  phone: string;
  orgId: string;
  orgName: string;
  roleNames: string[];
  roleCodes: string[];
  status: number;
  createTime: string;
  idaasUserId: string;
  appRoles: AppRole[];
}

let formState = reactive<Partial<User>>({});
const isNewIput = ref(true);
const encrypt = () => {
  isNewIput.value = false;
};
const decrypt = () => {
  isNewIput.value = true;
};
let validatePass = async (_rule: Rule, value: string) => {
  if (value && value !== formState.password) {
    return Promise.reject(new Error('请输入相同密码'));
  } else {
    return Promise.resolve();
  }
};
const pwdChange = async () => {
  if (formState.checkPassword) {
    await formRef.value.validateFields(['checkPassword']);
  }
};
const rules = {
  userName: [
    { required: true, message: '请输入用户名', trigger: 'change' },
    {
      trigger: 'change',
      pattern: /^[\u4E00-\u9FA5\x20a-zA-Z0-9_@.-]+$/,
      message: '可输入中英文、数字、下划线、中划线、.和@',
    },
    {
      trigger: 'change',
      min: 1,
      message: '至少输入1位字符',
    },
    {
      trigger: 'change',
      max: 64,
      message: '字符长度不超过64位',
    },
  ],
  name: [
    {
      trigger: 'change',
      min: 1,
      message: '至少输入1位字符',
    },
    {
      trigger: 'change',
      max: 85,
      message: '字符长度不超过85位',
    },
  ],
  email: [
    {
      pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
      message: '请输入正确的邮箱',
    },
  ],
  password: [
    {
      trigger: 'change',
      required: true,
      message: '请输入密码',
    },
    {
      pattern: /[a-zA-Z\d!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]{8,18}/,
      message: '请输入密码长度为8-18位,包含大小写字母、数字和特殊字符4类至少3类',
    },
  ],
  checkPassword: [
    { required: true, message: '请输入确认密码' },
    { validator: validatePass, trigger: 'change' },
  ],
  orgId: [
    {
      required: true,
      message: '请选择所属组织',
      trigger: 'change',
    },
  ],
};

const replaceFields = {
  children: 'children',
  label: 'name',
  value: 'id',
};
let visible = ref(props.visible);

let propsRef = reactive(props);
let type = ref(props.type);
function resetForm() {
  formRef.value.resetFields();
  formRef2.value.resetFields();
}
const phoneRule = ref<any>([]);
const emailRule = ref<any>([]);
const dynamicValidateForm = ref([
  {
    subAppId: '',
    idaasAppId: '',
    roleIds: [],
    roleList: [] as unknown as SaaSRoleItem[],
  },
]);
const treeData = ref<Partial<SaaSOrgItem[]>>([]);
async function fetchOrgTree() {
  let res = await getSaaSOrgTree();
  treeData.value = res;
}
const emit = defineEmits(['close']);

const handleCancel = () => {
  isNewIput.value = true;
  resetForm();
  formRef.value.clearValidate();
  emit('close', 'close');
};
const selectOrg = (value: string, node: SaaSOrgItem) => {
  formState.orgId = node.id;
};

const changeStatus = (checked: any) => {
  if (checked === 0) {
    formState.status = 0;
  } else {
    formState.status = 1;
  }
};
function setPhoneRule() {
  if (type.value === 1 || formState.isUpdatePhone) {
    phoneRule.value = [
      { required: formState.isUpdatePhone, message: '请输入手机号码', trigger: 'change' },
      {
        pattern: /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/,
        message: '请输入正确的手机号码',
      },
    ];
  } else {
    phoneRule.value = [];
  }
}
function setEmailRule() {
  if (type.value === 1 || formState.isUpdateEmail) {
    emailRule.value = [
      { required: formState.isUpdateEmail, message: '请输入邮箱', trigger: 'change' },
      {
        pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/,
        message: '请输入正确的邮箱',
      },
    ];
  } else {
    emailRule.value = [];
  }
}

const changePhoneStatus = (checked: any) => {
  formState.phone = undefined;
  formState.isUpdatePhone = checked;
  setPhoneRule();
};
const changeEmailStatus = (checked: any) => {
  formState.email = undefined;
  formState.isUpdateEmail = checked;
  setEmailRule();
};

function validate1() {
  return new Promise((resolve, reject) => {
    if (formRef.value.validate()) {
      resolve(true);
    } else {
      reject(new Error('表单验证失败'));
    }
  });
}

function validate2() {
  return new Promise((resolve, reject) => {
    if (formRef2.value.validate()) {
      resolve(true);
    } else {
      reject(new Error('表单验证失败'));
    }
  });
}
const handleOk = async () => {
  const p1 = validate1();
  const p2 = validate2();
  Promise.all([p1, p2]).then(async () => {
    const dsFormData = dynamicValidateForm.value;
    const values = { ...formState, appRoles: dsFormData };
    if (type.value === 1) {
      const res = await addSaaSUser(values);
      if (res) {
        message.success(ApiResultEnum.ADD_SUCCESS);
        resetForm();
        emit('close', 'success');
        handleCancel();
      } else {
        message.error(ApiResultEnum.ADD_FAIL);
        emit('close', 'close');
        handleCancel();
      }
    } else {
      const res = await updateSaaSUser(values);
      if (res) {
        message.success(ApiResultEnum.UPDATA_SUCCESS);
        formRef.value.clearValidate();
        emit('close', 'success');
        handleCancel();
      } else {
        message.error(ApiResultEnum.UPDATA_FAIL);
        emit('close', 'close');
        handleCancel();
      }
    }
  });
};
interface AppIdList {
  id: string;
  appId: string;
  console: boolean;
  createdBy: string;
  createdTime: string;
  domain: string;

  idaasAppId: string;
  name: string;
  status: string;
  disabled?: boolean;
}
let appIdList = ref<AppIdList[]>([]);
function findSubApp(subAppId: string) {
  const subApp = appIdList.value.filter((e) => e.id === subAppId)[0];
  return subApp;
}
async function handleSelect(subAppId: string, other: any) {
  let subApp = findSubApp(subAppId);
  subApp.disabled = true;
  dynamicValidateForm.value[other.key]['idaasAppId'] = unref(subApp)['idaasAppId'];
  let roleList: any[] = [];
  roleList = await getRoleBySubAppId({ subAppId: subAppId });
  dynamicValidateForm.value[other.key]['roleList'] = roleList;
  return roleList;
}
const remove = (item: number) => {
  let subApp = findSubApp(dynamicValidateForm.value[item].subAppId);
  if (subApp) subApp.disabled = false;
  dynamicValidateForm.value.splice(item, 1);
};
const addSight = () => {
  dynamicValidateForm.value.push({
    subAppId: '',
    idaasAppId: '',
    roleIds: [],
    roleList: [],
  });
};
function getSubApp() {
  getSubAppList().then((res) => {
    appIdList.value = res as AppIdList[];
  });
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const watchSelcted = watch(
  dynamicValidateForm,
  () => {
    appIdList.value.forEach((e) => {
      for (let item of dynamicValidateForm.value) {
        if (item.subAppId === e.id) {
          e.disabled = true;
          break;
        } else {
          e.disabled = false;
        }
      }
    });
  },
  {
    deep: true,
  }
);
async function getUserRole(id: string) {
  const userRoleData = await findSaaSUserRoleById({
    // eslint-disable-next-line camelcase
    user_id: id,
  });
  return userRoleData;
}
const autoSelect = async (appRolesInfoList: any) => {
  const roleInfoList = [];
  for (const appRole of appRolesInfoList) {
    let subApp = findSubApp(appRole.subAppId);
    subApp.disabled = true;
    let roleList = await getRoleBySubAppId({ subAppId: appRole.subAppId });
    let roleInfo = {
      subAppId: appRole.subAppId,
      idaasAppId: appIdList.value.find((app) => app.id === appRole.subAppId).idaasAppId,
      roleIds: [],
      roleList,
    };
    appRole.roles.forEach((e: any) => {
      roleInfo.roleIds.push(e.roleId);
    });
    roleInfoList.push(roleInfo);
  }
  dynamicValidateForm.value = roleInfoList;
};
watch(propsRef, async (newValue) => {
  visible.value = newValue.visible;
  type.value = newValue.type;
  if (newValue.visible) {
    fetchOrgTree();
    getSubApp();
  }
  await nextTick();
  if (type.value === 1) {
    resetForm();
    formState.isUpdatePhone = true;
    formState.idaasUserId = '';
    formState.userId = '';
    dynamicValidateForm.value = [
      {
        subAppId: '',
        idaasAppId: '',
        roleIds: [],
        roleList: [] as unknown as SaaSRoleItem[],
      },
    ];
  }
  setPhoneRule();
  setEmailRule();
  // 编辑
  if (type.value === 2 && visible.value === true) {
    const userRoleData = await getUserRole(newValue.user?.id);
    const { appRoles } = await viewSaaSUser({ userId: newValue.user.id });

    const roleIds: string[] = [];
    userRoleData.forEach((item: any) => {
      roleIds.push(item.id);
    });
    formState.userId = newValue.user?.id;
    formState.userName = newValue.user?.userName;
    formState.status = ~~newValue.user?.status;
    formState.phone = newValue.user?.phone;
    formState.orgId = newValue.user?.orgId;
    formState.name = newValue.user?.name;
    formState.email = newValue.user?.email;
    formState.idaasUserId = newValue.user?.idaasUserId;
    formState.isUpdatePhone = false;
    formState.isUpdateEmail = false;
    dynamicValidateForm.value = appRoles;
    autoSelect(appRoles);
  }
});
</script>
<style lang="less"></style>
